home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / shells / tcshsrc.zoo / tcsh / tc.sig.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-09  |  9.2 KB  |  426 lines

  1. /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.00/RCS/tc.sig.c,v 3.3 1991/08/06 01:49:53 christos Exp $ */
  2. /*
  3.  * sh.sig.c: Signal routine emulations
  4.  */
  5. /*-
  6.  * Copyright (c) 1980, 1991 The Regents of the University of California.
  7.  * All rights reserved.
  8.  *
  9.  * Redistribution and use in source and binary forms, with or without
  10.  * modification, are permitted provided that the following conditions
  11.  * are met:
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer.
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in the
  16.  *    documentation and/or other materials provided with the distribution.
  17.  * 3. All advertising materials mentioning features or use of this software
  18.  *    must display the following acknowledgement:
  19.  *    This product includes software developed by the University of
  20.  *    California, Berkeley and its contributors.
  21.  * 4. Neither the name of the University nor the names of its contributors
  22.  *    may be used to endorse or promote products derived from this software
  23.  *    without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35.  * SUCH DAMAGE.
  36.  */
  37. #include "config.h"
  38. RCSID("$Id: tc.sig.c,v 3.3 1991/08/06 01:49:53 christos Exp $")
  39.  
  40. #include "sh.h"
  41. /*
  42.  * a little complicated #include <sys/wait.h>! :-(
  43.  */
  44. #if SVID > 0
  45. # ifdef hpux
  46. #  ifndef __hpux
  47. #   include "tc.wait.h"    /* 6.5 broke <sys/wait.h> */
  48. #  else
  49. #   ifndef POSIX
  50. #    define _BSD
  51. #   endif
  52. #   ifndef _CLASSIC_POSIX_TYPES
  53. #    define _CLASSIC_POSIX_TYPES
  54. #   endif
  55. #   include <sys/wait.h> /* 7.0 fixed it again */
  56. #  endif /* __hpux */
  57. # else /* hpux */
  58. #  if defined(OREO) || defined(IRIS4D) || defined(POSIX)
  59. #   include <sys/wait.h>
  60. #  else    /* OREO || IRIS4D || POSIX */
  61. #   include "tc.wait.h"
  62. #  endif /* OREO || IRIS4D || POSIX */
  63. # endif    /* hpux */
  64. #else /* SVID == 0 */
  65. # include <sys/wait.h>
  66. #endif /* SVID == 0 */
  67.  
  68. #ifndef BSDSIGS
  69.  
  70. /* this stack is used to queue signals
  71.  * we can handle up to MAX_CHLD outstanding children now;
  72.  */
  73. #define MAX_CHLD 50
  74. static struct mysigstack {
  75.     int     s_w;        /* wait report             */
  76.     int     s_errno;        /* errno returned;         */
  77.     pid_t   s_pid;        /* pid returned             */
  78. }       stk[MAX_CHLD];
  79. static int stk_ptr = -1;
  80.  
  81.  
  82. #if SVID < 3 || defined(UNIXPC)
  83. /* queue child signals
  84.  */
  85. static sigret_t
  86. sig_ch_queue()
  87. {
  88. #ifdef JOBDEBUG
  89.     xprintf("queue SIGCHLD\n");
  90.     flush();
  91. #endif /* JOBDEBUG */
  92.     stk_ptr++;
  93.     stk[stk_ptr].s_pid = (pid_t) wait(&stk[stk_ptr].s_w);
  94.     stk[stk_ptr].s_errno = errno;
  95.     (void) signal(SIGCHLD, sig_ch_queue);
  96. #ifndef SIGVOID
  97.     return(0);
  98. #endif /* SIGVOID */
  99. }
  100.  
  101. /* process all awaiting child signals
  102.  */
  103. static sigret_t
  104. sig_ch_rel()
  105. {
  106.     while (stk_ptr > -1)
  107.     pchild(SIGCHLD);
  108. #ifdef JOBDEBUG
  109.     xprintf("signal(SIGCHLD, pchild);\n");
  110. #endif /* JOBDEBUG */
  111.     (void) signal(SIGCHLD, pchild);
  112. #ifndef SIGVOID
  113.     return(0);
  114. #endif /* SIGVOID */
  115. }
  116.  
  117. /* libc.a contains these functions in SVID >= 3. */
  118. sigret_t
  119. (*sigset(a, b)) ()
  120.     int     a;
  121.     sigret_t  (*b) __P((int));
  122. {
  123.     return (signal(a, b));
  124. }
  125.  
  126. /* release signal
  127.  *    release all queued signals and
  128.  *    set the default signal handler
  129.  */
  130. void
  131. sigrelse(what)
  132.     int     what;
  133. {
  134.     if (what == SIGCHLD)
  135.     sig_ch_rel();
  136.  
  137. #ifdef notdef    /* XXX: Should not need that when compiled with SVID=1 */
  138. # ifdef UNIXPC    
  139.     if (what == SIGINT)
  140.         (void)signal(SIGINT, pintr);
  141. # endif
  142. #endif
  143. }
  144.  
  145. /* hold signal
  146.  * only works with child and interrupt
  147.  */
  148. void
  149. sighold(what)
  150.     int     what;
  151. {
  152.     if (what == SIGCHLD)
  153.     (void) signal(SIGCHLD, sig_ch_queue);
  154.  
  155. #ifdef notdef    /* XXX: Should not need that when compiled with SVID=1 */
  156. # ifdef UNIXPC    
  157.     if (what == SIGINT)
  158.         (void)signal(SIGINT, SIG_IGN);
  159. # endif
  160. #endif
  161. }
  162.  
  163. /* ignore signal
  164.  */
  165. void
  166. sigignore(a)
  167.     int     a;
  168. {
  169.     (void) signal(a, SIG_IGN);
  170. }
  171.  
  172. /* atomically release one signal
  173.  */
  174. void
  175. sigpause(what)
  176.     int     what;
  177. {
  178. #ifdef notdef
  179.     if (what == SIGCHLD) {
  180.     if (stk_ptr > -1) {
  181.         pchild(SIGCHLD);
  182.     }
  183.     else {
  184.         (void) sleep(1);
  185.     }
  186.     }
  187. #endif
  188.     /* From: Jim Mattson <mattson%cs@ucsd.edu> */
  189.     if (what == SIGCHLD)
  190.     pchild(SIGCHLD);
  191.  
  192. }
  193.  
  194. #endif /* SVID < 3 || (UNIXPC) */
  195.  
  196. #ifdef SXA
  197. /*
  198.  * SX/A is SVID3 but does not have sys5-sigpause().
  199.  * I've heard that sigpause() is not defined in SVID3.
  200.  */
  201. /* This is not need if you make tcsh by BSD option's cc. */
  202. void
  203. sigpause(what)
  204. {
  205.     if (what == SIGCHLD) {
  206.     bsd_sigpause(bsd_sigblock((sigmask_t) 0) & ~sigmask(SIGBSDCHLD));
  207.     }
  208.     else if (what == 0) {
  209.     pause();
  210.     }
  211.     else {
  212.     xprintf("sigpause(%d)\n", what);
  213.     pause();
  214.     }
  215. }
  216.  
  217. #endif /* SXA */
  218.  
  219. /* return either awaiting processes or do a wait now
  220.  */
  221. pid_t
  222. ourwait(w)
  223.     int    *w;
  224. {
  225.     pid_t pid;
  226.  
  227. #ifdef JOBDEBUG
  228.     xprintf("our wait %d\n", stk_ptr);
  229.     flush();
  230. #endif /* JOBDEBUG */
  231.  
  232.     if (stk_ptr == -1) {
  233.     /* stack empty return signal from stack */
  234.     pid = (pid_t) wait(w);
  235. #ifdef JOBDEBUG
  236.     xprintf("signal(SIGCHLD, pchild);\n");
  237. #endif /* JOBDEBUG */
  238.     (void) signal(SIGCHLD, pchild);
  239.     return (pid);
  240.     }
  241.     else {
  242.     /* return signal from stack */
  243.     errno = stk[stk_ptr].s_errno;
  244.     *w = stk[stk_ptr].s_w;
  245.     stk_ptr--;
  246.     return (stk[stk_ptr + 1].s_pid);
  247.     }
  248. } /* end ourwait */
  249.  
  250. #endif /* BSDSIGS */
  251.  
  252. #ifdef NEEDsignal
  253. /* turn into bsd signals */
  254. sigret_t(*
  255.      xsignal(s, a)) ()
  256.     int     s;
  257.     sigret_t (*a) __P((int));
  258. {
  259.     sigvec_t osv, sv;
  260.  
  261.     (void) mysigvec(s, NULL, &osv);
  262.     sv = osv;
  263.     sv.sv_handler = a;
  264. #ifdef SIG_STK
  265.     sv.sv_onstack = SIG_STK;
  266. #endif
  267. #if defined(SV_BSDSIG) && defined(SV_ONSTACK)
  268.     sv.sv_flags = SV_BSDSIG | SV_ONSTACK;
  269. #endif
  270.  
  271.     if (mysigvec(s, &sv, NULL) < 0)
  272.     return (BADSIG);
  273.     return (osv.sv_handler);
  274. }
  275.  
  276. #endif /* NEEDsignal */
  277.  
  278. #ifdef _SEQUENT_
  279. /*
  280.  * Support for signals.
  281.  */
  282.  
  283. extern int errno;
  284.  
  285. /* Set and test a bit.  Bits numbered 1 to 32 */
  286.  
  287. #define SETBIT(x, y)    x |= sigmask(y)
  288. #define ISSET(x, y)    ((x & sigmask(y)) != 0)
  289.  
  290. #ifdef DEBUG
  291. # define SHOW_SIGNALS    1    /* to assist in debugging signals */
  292. #endif
  293.  
  294. #ifdef SHOW_SIGNALS
  295. char   *show_sig_mask();
  296. #endif
  297.  
  298. int     debug_signals = 0;
  299.  
  300. /*
  301.  * igsetmask(mask)
  302.  *
  303.  * Set a new signal mask.  Return old mask.
  304.  */
  305. sigmask_t
  306. sigsetmask(mask)
  307.     sigmask_t     mask;
  308. {
  309.     sigset_t set, oset;
  310.     int     m;
  311.     register int i;
  312.  
  313.     sigemptyset(&set);
  314.     sigemptyset(&oset);
  315.  
  316.     for (i = 1; i <= MAXSIG; i++)
  317.     if (ISSET(mask, i))
  318.         sigaddset(&set, i);
  319.  
  320.     if (sigprocmask(SIG_SETMASK, &set, &oset))
  321.     xprintf("sigsetmask(0x%x) - sigprocmask failed, errno %d",
  322.         mask, errno);
  323.  
  324.     m = 0;
  325.     for (i = 1; i < MAXSIG; i++)
  326.     if (sigismember(&oset, i))
  327.         SETBIT(m, i);
  328.  
  329.     return (m);
  330. }
  331.  
  332. /*
  333.  * sigblock(mask)
  334.  *
  335.  * Add "mask" set of signals to the present signal mask.
  336.  * Return old mask.
  337.  */
  338. sigmask_t
  339. sigblock(mask)
  340.     sigmask_t     mask;
  341. {
  342.     sigset_t set, oset;
  343.     int     m;
  344.     register int i;
  345.  
  346.     set = 0;
  347.     oset = 0;
  348.  
  349.     /* Get present set of signals. */
  350.     if (sigprocmask(SIG_SETMASK, NULL, &set))
  351.     xprintf("sigblock(0x%x) - sigprocmask failed, errno %d",
  352.         mask, errno);
  353.  
  354.     /* Add in signals from mask. */
  355.     for (i = 1; i <= MAXSIG; i++)
  356.     if (ISSET(mask, i))
  357.         sigaddset(&set, i);
  358.  
  359.     sigprocmask(SIG_SETMASK, &set, &oset);
  360.  
  361.     /* Return old mask to user. */
  362.     m = 0;
  363.     for (i = 1; i < MAXSIG; i++)
  364.     if (sigismember(&oset, i))
  365.         SETBIT(m, i);
  366.  
  367.     return (m);
  368. }
  369.  
  370.  
  371. /*
  372.  * bsd_sigpause(mask)
  373.  *
  374.  * Set new signal mask and wait for signal;
  375.  * Old mask is restored on signal.
  376.  */
  377. void
  378. bsd_sigpause(mask)
  379.     sigmask_t     mask;
  380. {
  381.     sigset_t set;
  382.     register int i;
  383.  
  384.     sigemptyset(&set);
  385.  
  386.     for (i = 1; i <= MAXSIG; i++)
  387.     if (ISSET(mask, i))
  388.         sigaddset(&set, i);
  389.     sigsuspend(&set);
  390. }
  391. #endif /* _SEQUENT_ */
  392.  
  393.  
  394. #ifdef SIGSYNCH
  395. static long Synch_Cnt = 0;
  396.  
  397. sigret_t
  398. synch_handler(sno)
  399. int sno;
  400. {
  401.     if (sno != SIGSYNCH)
  402.     abort();
  403.     Synch_Cnt++;
  404. }
  405. #endif /* SIGSYNCH */
  406.  
  407. #ifdef __MINT__
  408. /* MiNT has most BSD signal things, but not sigvec; punt */
  409. void
  410. mysigvec(sig, new, old)
  411.     int sig;
  412.     sigvec_t *new, *old;
  413. {
  414.     void (*oldhandler)();
  415.  
  416.     if (new) {
  417.         oldhandler = signal(sig, new->sv_handler);
  418.     } else {
  419.         oldhandler = signal(sig, SIG_IGN);
  420.         signal(sig, oldhandler);
  421.     }
  422.     if (old)
  423.         old->sv_handler = oldhandler;
  424. }
  425. #endif /* __MINT__ */
  426.